package com.smart.community.common.config;


import com.smart.community.common.realm.UserRealm;
import com.smart.community.common.session.CustomSessionManager;
import com.smart.community.common.utils.ShiroUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * @author zhangwei
 * 1.  注册自动 Realm
 * 2.  注册 SecurityManager
 * 3.  白名单过滤器 ShiroFilterChainDefinition
 * 4.  注册密码加密器
 */
@Configuration
@EnableConfigurationProperties(ShiroProperties.class)
public class ShiroConfig {

    @Resource
    private ShiroProperties shiroProperties;

    private static final String DEFINITION = "anon";

    /**
     * 容器中注册
     *
     * @return
     */
    @Bean
    public UserRealm realm(HashedCredentialsMatcher hashedCredentialsMatcher) {
        UserRealm userRealm = new UserRealm();
        userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return userRealm;
    }


    /**
     *
     */
    @Bean
    public DefaultWebSecurityManager securityManager(UserRealm realm, CustomSessionManager customSessionManager) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        // 注册自定义Realm
        defaultWebSecurityManager.setRealm(realm);
        defaultWebSecurityManager.setSessionManager(customSessionManager);
        return defaultWebSecurityManager;
    }

    /**
     * 1. 过滤白名单
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        //白名单
        for (String s : shiroProperties.getDischargedUrl()) {
            chainDefinition.addPathDefinition(s, DEFINITION);
        }
        // 表示其他所有接口的需要认证
        chainDefinition.addPathDefinition("/**", "authc");
        return chainDefinition;
    }

    /**
     * cookie + session
     * jwt
     */
    @Bean
    public CustomSessionManager sessionManager() {
        CustomSessionManager customSessionManager = new CustomSessionManager();
        // session的过期时间
        //   -1  表示永不过期
        //   0   表示浏览器断开连接就会失效
        //   >0   表示设置具体的过期时间
        customSessionManager.setGlobalSessionTimeout(7 * 24 * 60 * 60 * 1000);
        customSessionManager.setSessionIdCookieEnabled(true);
        customSessionManager.setSessionIdUrlRewritingEnabled(false);
        return customSessionManager;
    }

    /**
     * 注册到容器
     *
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
        hashedCredentialsMatcher.setHashIterations(ShiroUtils.HASH_ITERATIONS);
        return hashedCredentialsMatcher;
    }
}
